package com.android.lovely.ext

import android.content.Context
import android.os.Environment
import com.android.lovely.api.service.downloadService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okio.buffer
import okio.sink
import okio.source
import java.io.File
import java.io.IOException

/**
 *
 * @author why
 * @date 2025/3/24 21:27
 */

/**
 * 下载图片到本地
 * @param url 图片URL
 * @return Result<Boolean> 下载结果
 */
suspend fun Context.downloadImage(url: String): Result<Boolean> = withContext(Dispatchers.IO) {
    try {
        // 1. 验证URL
        if (url.isBlank()) {
            return@withContext Result.failure(IllegalArgumentException("URL cannot be empty"))
        }

        // 2. 生成文件名
        val fileName = url.substringBefore("?").substringAfterLast("/")
        if (fileName.isBlank()) {
            return@withContext Result.failure(IllegalArgumentException("Invalid file name from URL"))
        }

        // 3. 创建输出文件
        val outputFile = File(cacheDir, fileName)
        if (outputFile.exists() && outputFile.length() > 0) {
            // 文件已存在且不为空，直接返回成功
            return@withContext Result.success(true)
        }

        // 4. 下载文件
        val isSuccess = url.download(outputFile.absolutePath)

        if (!isSuccess) {
            return@withContext Result.failure(RuntimeException("Download failed"))
        }

        // 5. 复制到公共目录
        try {
            outputFile.copyInToPublic()
            Result.success(true)
        } catch (e: IOException) {
            // 复制失败但下载成功，返回部分成功
            Result.success(true)
        }
    } catch (e: Exception) {
        Result.failure(e)
    }
}

/**
 * 扩展函数：复制文件到公共目录
 * @throws IOException 如果复制失败
 */
private fun File.copyInToPublic() {
    val publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
    if (!publicDir.exists()) {
        publicDir.mkdirs()
    }
    
    val destFile = File(publicDir, name)
    if (destFile.exists()) {
        destFile.delete()
    }
    copyTo(destFile, overwrite = true)
}

/**
 * 下载文件
 * @param url 文件URL
 * @param outputPath 输出路径
 * @return Boolean 是否下载成功
 */
private suspend fun String.download(outputPath: String): Boolean = withContext(Dispatchers.IO) {
    runCatching {
        val responseBody = downloadService.downloadFile(this@download)
        
        val outputFile = File(outputPath)
        outputFile.parentFile?.mkdirs()
        if (outputFile.exists()) outputFile.delete()
        outputFile.createNewFile()

        outputFile.sink().buffer().use { sink ->
            responseBody.source().use { source ->
                sink.writeAll(source)
                sink.flush()
            }
        }
        true
    }.getOrDefault(false)
}